package com.lzh.persevere.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzh.persevere.common.BaseEntity;
import com.lzh.persevere.config.constant.ModuleConstants;
import com.lzh.persevere.mapper.*;
import com.lzh.persevere.model.entity.Comment;
import com.lzh.persevere.model.entity.DislikeInfo;
import com.lzh.persevere.model.entity.FileInfo;
import com.lzh.persevere.model.entity.LikeInfo;
import com.lzh.persevere.model.qo.comment.CommentPageQO;
import com.lzh.persevere.model.qo.comment.ExpandSubCommentQO;
import com.lzh.persevere.model.ro.comment.SendCommentRO;
import com.lzh.persevere.model.vo.comment.CommentVO;
import com.lzh.persevere.service.CommentService;
import com.lzh.persevere.template.PageAbstractTemplate;
import com.lzh.persevere.utils.IpUtil;
import com.lzh.persevere.utils.SecurityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 评论表服务实现类
 *
 * @author luzhiheng
 * @since 2025-07-07
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private RedisCacheService redisCacheService;

    @Resource
    private LikeInfoMapper likeInfoMapper;

    @Resource
    private DislikeInfoMapper dislikeInfoMapper;

    @Resource
    private FileInfoMapper fileInfoMapper;

    @Resource
    private ArticleInfoMapper articleInfoMapper;

    @Override
    public Map<String, Object> pageList(CommentPageQO qo) {
        Map<String, Object> otherQueryMap = new HashMap<>();
        PageAbstractTemplate template = new PageAbstractTemplate() {
            @Override
            public Integer countTotal() {
                return baseMapper.countList(getQueryMap(qo.getPageModel(), otherQueryMap));
            }

            @Override
            public List<Map<String, Object>> queryPageList() {
                // 分页查询根评论列表
                List<Map<String, Object>> pageList = baseMapper.getPageList(queryMap);
                if (CollectionUtil.isEmpty(pageList)) {
                    return pageList;
                }
                Long userId = SecurityUtils.getUserId();
                Map<String, String> userIdNickNameMap = redisCacheService.getAllUserIdNickNameMap();
                Map<String, String> userIdAvatarMap = redisCacheService.getAllUserIdAvatarMap();

                // 获取根评论ID列表
                List<Long> commentIdList = pageList.stream().map(e -> (Long) e.get("id")).collect(Collectors.toList());
                // 获取根评论图片文件id列表
                List<Long> imageFileInfoIdList = new ArrayList<>();
                pageList.forEach(e -> {
                    Object imagesObj = e.get("images");
                    if (imagesObj != null) {
                        String[] split = String.valueOf(imagesObj).split(",");
                        for (String str : split) {
                            imageFileInfoIdList.add(Long.valueOf(str));
                        }
                    }
                });


                // 获取有子评论的根评论ID列表
                List<Long> rootCommentIdList = pageList.stream()
                        .filter(e -> e.get("subCommentCount") != null && Integer.parseInt(e.get("subCommentCount").toString()) > 0)
                        .map(e -> (Long) e.get("id")).collect(Collectors.toList());
                Map<Long, CommentVO> rootCommentIdMap;
                if (CollectionUtil.isNotEmpty(rootCommentIdList)) {
                    // 获取最新一条的子评论列表
                    List<CommentVO> subCommentList = baseMapper.selectLatestSubComment(rootCommentIdList);
                    rootCommentIdMap = subCommentList.stream().collect(Collectors.toMap(CommentVO::getRootCommentId, e -> e, (k1, k2) -> k1));
                    List<Long> subCommentIdList = subCommentList.stream().map(CommentVO::getId).collect(Collectors.toList());
                    commentIdList.addAll(subCommentIdList);

                    subCommentList.forEach(e -> {
                        Object imagesObj = e.getImages();
                        if (imagesObj != null) {
                            String[] split = String.valueOf(imagesObj).split(",");
                            for (String str : split) {
                                imageFileInfoIdList.add(Long.valueOf(str));
                            }
                        }
                    });
                } else {
                    rootCommentIdMap = new HashMap<>();
                }

                Map<Long, String> fileInfoIdImageAddressMap;
                if (CollectionUtil.isNotEmpty(imageFileInfoIdList)) {
                    List<FileInfo> fileInfos = fileInfoMapper.selectByIdList(imageFileInfoIdList);
                    fileInfoIdImageAddressMap = fileInfos.stream().collect(Collectors.toMap(BaseEntity::getId, FileInfo::getFileAddress));
                } else {
                    fileInfoIdImageAddressMap = new HashMap<>();
                }

                // 获取点赞信息
                List<LikeInfo> likeInfoList = likeInfoMapper.selectByCommentIdList(commentIdList);
                // 获取点踩信息
                List<DislikeInfo> dislikeInfoList = dislikeInfoMapper.selectByCommentIdList(commentIdList);

                Map<Long, String> userLikeCommentIdMap;
                Map<Long, String> userDislikeCommentIdMap;
                if (userId != null) {
                    // 用户已登陆
                    userLikeCommentIdMap = likeInfoList.stream().filter(e -> e.getCreateUserId().equals(userId.toString())).collect(Collectors.toMap(LikeInfo::getLikeCommentId, BaseEntity::getCreateUserId));
                    userDislikeCommentIdMap = dislikeInfoList.stream().filter(e -> e.getCreateUserId().equals(userId.toString())).collect(Collectors.toMap(DislikeInfo::getDislikeCommentId, BaseEntity::getCreateUserId));
                } else {
                    // 用户未登陆
                    userLikeCommentIdMap = new HashMap<>();
                    userDislikeCommentIdMap = new HashMap<>();
                }

                pageList.forEach(map -> {
                    if (map.get("ip") != null) {
                        map.put("city", IpUtil.getCityInfoByIp(String.valueOf(map.get("ip"))));
                    }
                    String createUserId = String.valueOf(map.get("createUserId"));
                    map.put("createUserNickname", userIdNickNameMap.get(createUserId));
                    map.put("avatar", userIdAvatarMap.get(createUserId));
                    map.put("isLike", userLikeCommentIdMap.containsKey(Long.valueOf(map.get("id").toString())));
                    map.put("isDislike", userDislikeCommentIdMap.containsKey(Long.valueOf(map.get("id").toString())));

                    List<String> imageList = new ArrayList<>();
                    if (map.get("images") != null) {
                        String[] split = String.valueOf(map.get("images")).split(",");
                        for (String str : split) {
                            String imageAddress = fileInfoIdImageAddressMap.get(Long.valueOf(str));
                            imageList.add(imageAddress);
                        }
                    }
                    map.put("imageList", imageList);

                    CommentVO subLatestComment = rootCommentIdMap.get((Long) map.get("id"));
                    if (subLatestComment != null) {
                        if (StrUtil.isNotEmpty(subLatestComment.getIp())) {
                            subLatestComment.setCity(IpUtil.getCityInfoByIp(subLatestComment.getIp()));
                        }
                        String createUserIdStr = String.valueOf(subLatestComment.getCreateUserId());
                        subLatestComment.setCreateUserNickname(userIdNickNameMap.get(createUserIdStr));
                        subLatestComment.setToCommentUserNickname(userIdNickNameMap.get(String.valueOf(subLatestComment.getToCommentUserId())));
                        subLatestComment.setAvatar(userIdAvatarMap.get(createUserIdStr));
                        subLatestComment.setIsLike(userLikeCommentIdMap.containsKey(subLatestComment.getId()));
                        subLatestComment.setIsDislike(userDislikeCommentIdMap.containsKey(subLatestComment.getId()));
                        subLatestComment.setImageList(new ArrayList<>());
                        if (StrUtil.isNotEmpty(subLatestComment.getImages())) {
                            String[] split = String.valueOf(subLatestComment.getImages()).split(",");
                            for (String str : split) {
                                String imageAddress = fileInfoIdImageAddressMap.get(Long.valueOf(str));
                                subLatestComment.getImageList().add(imageAddress);
                            }
                        }
                        map.put("replies", Collections.singletonList(subLatestComment));
                    }
                });
                return pageList;
            }
        };
        return template.queryPage();
    }

    @Override
    public CommentVO sendComment(SendCommentRO ro) {
        Comment comment = Comment.builder()
                .moduleId(ro.getModuleId())
                .rootCommentId(ro.getRootCommentId())
                .toCommentId(ro.getToCommentId())
                .toCommentUserId(ro.getToCommentUserId())
                .content(ro.getContent())
                .ip(IpUtil.getIpAddress())
                .build();
        if (CollectionUtil.isNotEmpty(ro.getImageFileIdList())) {
            String images = ro.getImageFileIdList().stream().map(String::valueOf).collect(Collectors.joining(","));
            comment.setImages(images);
        }
        baseMapper.insert(comment);

        if (ro.getToCommentUserId() != null) {
            // 子评论，更新父评论的子评论数
            baseMapper.updateSubCommentCount(ro.getRootCommentId(), 1);
        }
        CommentVO commentVO = BeanUtil.copyProperties(comment, CommentVO.class);
        commentVO.setCity(IpUtil.getCityInfoByIp());

        if (ro.getModuleId().startsWith(ModuleConstants.ARTICLE + "@")) {
            // 文章评论，则需要更新文章评论数
            articleInfoMapper.updateCommentCount(ro.getModuleId().split("@")[1], 1, SecurityUtils.getUserId());
        }

        return commentVO;
    }

    @Override
    public Map<String, Object> expandMoreSubComment(ExpandSubCommentQO qo) {
        Map<String, Object> result = new HashMap<>();
        String moduleId = qo.getModuleId();
        Long rootCommentId = qo.getRootCommentId();
        List<CommentVO> curSubCommentList = qo.getCurSubCommentList();
        Long userId = SecurityUtils.getUserId();
        List<Long> curSubCommentIds = curSubCommentList.stream().map(CommentVO::getId).collect(Collectors.toList());

        Map<String, String> userIdNickNameMap = redisCacheService.getAllUserIdNickNameMap();
        Map<String, String> userIdAvatarMap = redisCacheService.getAllUserIdAvatarMap();
        List<CommentVO> moreSubCommentList = baseMapper.selectMoreSubComment(moduleId, rootCommentId, curSubCommentIds);
        List<Long> commentIdList = moreSubCommentList.stream().map(CommentVO::getId).collect(Collectors.toList());

        // 获取点赞信息
        Map<Long, DislikeInfo> userLikeCommentIdMap;
        // 获取点踩信息
        Map<Long, DislikeInfo> userDislikeCommentIdMap;
        if (userId != null) {
            // 用户已登陆
            userLikeCommentIdMap = likeInfoMapper.selectByCommentIdListAndCreateUserId(commentIdList, userId);
            userDislikeCommentIdMap = dislikeInfoMapper.selectByCommentIdListAndCreateUserId(commentIdList, userId);
        } else {
            // 用户未登陆
            userLikeCommentIdMap = new HashMap<>();
            userDislikeCommentIdMap = new HashMap<>();
        }

        List<Long> fileInfoIdList = new ArrayList<>();
        for (CommentVO vo : moreSubCommentList) {
            if (StrUtil.isNotEmpty(vo.getImages())) {
                for (String str : vo.getImages().split(",")) {
                    fileInfoIdList.add(Long.valueOf(str));
                }
            }
        }

        Map<Long, String> fileInfoIdImageAddressMap;
        if (CollectionUtil.isNotEmpty(fileInfoIdList)) {
            List<FileInfo> fileInfoList = fileInfoMapper.selectByIdList(fileInfoIdList);
            fileInfoIdImageAddressMap = CollectionUtil.isNotEmpty(moreSubCommentList) ? fileInfoList.stream().collect(Collectors.toMap(BaseEntity::getId, FileInfo::getFileAddress)) : new HashMap<>();
        } else {
            fileInfoIdImageAddressMap = new HashMap<>();
        }
        moreSubCommentList.forEach(e -> {
            if (StrUtil.isNotEmpty(e.getIp())) {
                e.setCity(IpUtil.getCityInfoByIp(e.getIp()));
            }
            String createUserIdStr = String.valueOf(e.getCreateUserId());
            e.setCreateUserNickname(userIdNickNameMap.get(createUserIdStr));
            e.setToCommentUserNickname(userIdNickNameMap.get(String.valueOf(e.getToCommentUserId())));
            e.setAvatar(userIdAvatarMap.get(createUserIdStr));
            e.setIsLike(userLikeCommentIdMap.containsKey(e.getId()));
            e.setIsDislike(userDislikeCommentIdMap.containsKey(e.getId()));
            e.setImageList(new ArrayList<>());
            if (StrUtil.isNotEmpty(e.getImages())) {
                for (String str : e.getImages().split(",")) {
                    e.getImageList().add(fileInfoIdImageAddressMap.get(Long.valueOf(str)));
                }
            }
        });

        result.put("moreSubCommentList", moreSubCommentList);
        return result;
    }
}
